#!/bin/bash

# ----------------------------------------------------------------------
# Filename:   Partition_parted.sh
# Version:    1.0
# Date:       2014/06/23
# Author:     xi.zhang
# Email:      xi.zhang@cs2c.com.cn
# Summary:    Create a partition and delete a partition by parted command
# Notes:      Create a extended partition and delete a partition
# Copyright:  China Standard Software Co., Ltd.
# History：     
#             Version 1.0, 2014/06/23
#             - The first one
#             Version 1.1,2014/11/13
#             - The second one
#             - Add verification of the last partition which is extended partition
# ----------------------------------------------------------------------

source ${SFROOT}/lib/Echo.sh

##! @TODO: Create a extended partition when nothing extended partition exists.
##! @AUTHOR: xi.zhang
##! @VERSION: 1.0 
##! @OUT: Add a extended partition.
##! @TODO: Get Hard Disk Device.
##! @AUTHOR: xi.zhang
##! @VERSION: 1.0 
##! @OUT: Get Hard Disk Device Name.
function GetHarddisk()
{
    export HARD_DISK=`blkid | awk -F ":" '{print $1}' | sed -n '1p' |tr -d "0-9"`
    #export HARD_DISK=`fdisk -l | awk '{print $1}' | sed -n '$p' | tr -d "0-9"`
    if [ -n ${HARD_DISK} ];then
        EchoInfo "get hard disk device:${HARD_DISK}"
    fi
}

function CreateExtended ()
{
    parted -s ${HARD_DISK} mkpart extended ${STARTBLOCK}GB ${TOTAL}GB
    EchoResult "create extended"

    # get created extend partition, through grep extended and tail line, check extended partition
    EXTENDED_PART=`parted -s ${HARD_DISK} print | grep extended | awk '{print $1}' |tr -d ''`
    [ "x" != x${EXTENDED_PART} -a ${EXTENDED_PART} = `parted -s ${HARD_DISK} print |tail -2 | awk '/./{print $1}'` ]
    EchoResult "get created extended partition: ${EXTENDED_PART}"

    CreateLogical
}

##! @TODO: Create a logical partition when extended partition has existed.
##! @AUTHOR: xi.zhang
##! @VERSION: 1.0 
##! @OUT: Add a logical partition.

function CreateLogical ()
{
# from last partition END ~ END+5 or END ~ TOTAL
    DISKSIZE=5  #set patition size 
    ENDBLOCK=`echo "${STARTBLOCK}+${DISKSIZE}" | bc`
    if [ ${ENDBLOCK} -ge ${TOTAL} ];then
        ENDBLOCK=${TOTAL}
    fi

    parted -s ${HARD_DISK} mkpart logic ${STARTBLOCK}GB ${ENDBLOCK}GB  
    EchoResult "Create Logical Partition"

    # get created logical partition
    LOGICAL_PART=`parted -s ${HARD_DISK} print |tail -2 | awk '/./{print $1}'`
    if [ "x" != x${LOGICAL_PART} ];then
        EchoInfo "get created logical partition:${LOGICAL_PART}"
        return ${LOGICAL_PART}
    else
        echo  -e "\033[31m FAIL\033[0m | get created logical partition"
        return 0
    fi

}

##! @TODO: Create a primary partition in gpt.
##! @AUTHOR: xi.zhang
##! @VERSION: 1.0 
##! @OUT: Add a primary partition.

function CreatePrimary ()
{
# from last partition END ~ END+5 or END ~ TOTAL
    DISKSIZE=5
    ENDBLOCK=`echo "${STARTBLOCK}+${DISKSIZE}" | bc`
    if [ $ENDBLOCK -ge $TOTAL ];then
        ENDBLOCK=${TOTAL}
    fi

    parted -s ${HARD_DISK} mkpart primary ${STARTBLOCK}GB ${ENDBLOCK}GB  
    EchoResult "create primary"

    # get created primary partition
    PRIMARY_PART=`parted -s ${HARD_DISK} print |tail -2 | awk '/./{print $1}'`
    if [ "x" != x${PRIMARY_PART} ];then
        EchoInfo "get created primary partition: ${PRIMARY_PART}"
        return ${PRIMARY_PART}
    else
        echo  -e "\033[31m FAIL\033[0m | get primary logical partition"
        return 0
    fi

}

##! @TODO: Create a extended partition in different conditions
##! @AUTHOR: yuanhui.shi
##! @VERSION: 1.0 
##! @OUT: Add a extended partition.

function CreatePartition ()
{
    HaveExtended=2

# check total block, is not null
    declare TOTAL=`parted -s ${HARD_DISK} print |grep Disk | awk -F ":" '{print $2}' | tr -d " GB"`
    [ -n ${TOTAL} ] 
    EchoResult "get total block of ${HARD_DISK}"

# check STARTBLOCK, if greate than TOTAL BLOCK, then fail
    export STARTBLOCK=`parted -s ${HARD_DISK} print |tail -2 | awk '/./{print $3}'| tr -d "GB"`
    [ -n ${STARTBLOCK} ]
    EchoResult "get start block of ${HARD_DISK}"
    
    export Partition_TYPE=`parted -s ${HARD_DISK} print |tail -2 | awk '/./{print $5}'`
   
    if [ $STARTBLOCK -eq $TOTAL ] && [ $Partition_TYPE = "logical" ]
    then
      echo "disk have not enough space to mkpart"   
    elif [ $STARTBLOCK -eq $TOTAL ] && [ $Partition_TYPE = "extended" ]
    then
        STARTBLOCK=`parted -s ${HARD_DISK} print |tail -2 | awk '/./{print $2}'| tr -d "GB"`
    fi

# get part table types, msdos or gpt
    PART_TABLE=`parted ${HARD_DISK} print | grep -i "Partition Table" | awk -F ":" '{print $2}' | tr -d ' ' | tr "A-Z" "a-z"`

    PRIMARY=`parted ${HARD_DISK} print | grep primary | wc -l`

    # check msdos
    if [ ${PART_TABLE} = "msdos" ];then

        # already has 4 primary partitions
        if [ $PRIMARY -ge 4 ];then
            HaveExtended=2
            EchoInfo "${PART_TABLE}: already have 4 primary partitions"
            exit 1
        # check extended partition
        elif [ -z "`parted -s ${HARD_DISK} print |grep extended`" ];then

            HaveExtended=1
            CreateExtended
        else
            HaveExtended=0
            logical=`parted -s ${HARD_DISK} print | tail -n 2 | awk '{print $1}'| tr -d "\n" `
            if [ ${logical} -ge 16 ];then
                EchoInfo "${logical}:Disk already have 16 partition"
                exit 1
            else
                CreateLogical
                return $?
            fi
        fi

    # check gpt
    elif  [ ${PART_TABLE} = "gpt" ];then

        # already has 128 primary partitions
        if [ $PRIMARY -ge 128 ];then
            HaveExtended=2
            EchoInfo "${PART_TABLE}: already have 128 primary partitions"
            exit 1
        else
            HaveExtended=3
            CreatePrimary
            return $?
        fi

    fi
  
}

##! @TODO: Delete a logical partition.
##! @AUTHOR: yuanhui.shi
##! @VERSION: 1.0 
##! @OUT: Delete a logical partition.

function DeleteLogical ()
{
    NUM=`parted -s ${HARD_DISK} print | tail -2 |tr -d "\n" | awk '{print $1}'`
    if [ "x" != x${NUM} ];then
        EchoInfo "to be deleted logical partition: ${NUM}"
    else
        echo  -e "\033[31m FAIL\033[0m | get logical partition to be deleted"
        exit 1
    fi

    parted -s ${HARD_DISK} rm ${NUM}
    EchoResult "rm partition ${NUM}"
#    return 0
}

##! @TODO: Delete a extended.
##! @AUTHOR: yuanhui.shi
##! @VERSION: 1.0 
##! @OUT: Delete the extended partition.

function DeleteExtended ()
{
#    NUM1=`diff -b /tmp/tmp1 /tmp/tmp2 | sed '1d'|cut -d " " -f3 | tac`
    if [ "x" != x${EXTENDED_PART} ];then
        EchoInfo "to be deleted logical partition: ${EXTENDED_PART}"
    else
        echo  -e "\033[31m FAIL\033[0m | get logical partition to be deleted"
        exit 1
    fi

    for i in $LOGICAL_PART $EXTENDED_PART
     do 
       {
         parted -s ${HARD_DISK} rm $i &>/dev/null
         EchoResult "rm partition $i"
       }
   done
#    return 0
}

##! @TODO: Delete a primary.
##! @AUTHOR: huijing.hei
##! @VERSION: 1.0 
##! @OUT: Delete the primary partition.

function DeletePrimary ()
{
#    NUM1=`diff -b /tmp/tmp1 /tmp/tmp2 | sed '1d'|cut -d " " -f3 | tac`
    if [ "x" != x${PRIMARY_PART} ];then
        EchoInfo "to be deleted primary partition: ${PRIMARY_PART}"
    else
        echo  -e "\033[31m FAIL\033[0m | get primary partition to be deleted"
        exit 1
    fi

    for i in $PRIMARY_PART
     do 
       {
         parted -s ${HARD_DISK} rm $i &>/dev/null
         EchoResult "rm partition $i"
       }
   done
#    return 0
}

##! @TODO: Delete a partition.
##! @AUTHOR: yuanhui.shi
##! @VERSION: 1.0 
##! @OUT: Delete the extended partition.

function DeletePartition ()
{  

#   if [ -n "`diff -b /tmp/tmp1 /tmp/tmp2`" ];then
      
#       {
        if [ "$HaveExtended" = 1 ] ;then 
               DeleteExtended
        elif [ "$HaveExtended" = 0 ] ;then
               DeleteLogical
        elif [ "$HaveExtended" = 3 ] ;then
               DeletePrimary
        elif  [ "$HaveExtended" = 2 ] ;then
               EchoInfo "no partition to be deleted"
        fi
#        }
#   fi     
   return 0
}
